สถาปัตยกรรม Progressive Web App: รูปแบบของ JavaScript Service Worker | MLOG | MLOG

4. เครือข่ายเท่านั้น (Network-Only)

กลยุทธ์เครือข่ายเท่านั้นจะดึงข้อมูลแอสเซทจากเครือข่ายเสมอ โดยไม่ผ่านแคชเลย กลยุทธ์นี้ใช้เมื่อคุณต้องการทรัพยากรเวอร์ชันล่าสุดอย่างแน่นอนและไม่ต้องการการแคช

ตัวอย่าง:

            
self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request)
  );
});

            

5. ข้อมูลเก่าขณะตรวจสอบใหม่ (Stale-While-Revalidate)

กลยุทธ์ stale-while-revalidate จะให้บริการแอสเซทที่แคชไว้ทันที ในขณะเดียวกันก็จะดึงเวอร์ชันล่าสุดจากเครือข่าย เมื่อคำขอเครือข่ายเสร็จสิ้น แคชจะถูกอัปเดตด้วยเวอร์ชันใหม่ กลยุทธ์นี้ให้การตอบสนองเริ่มต้นที่รวดเร็ว ในขณะที่ทำให้แน่ใจว่าผู้ใช้จะได้รับเนื้อหาที่ทันสมัยที่สุดในที่สุด นี่เป็นกลยุทธ์ที่เป็นประโยชน์สำหรับเนื้อหาที่ไม่สำคัญมาก แต่ต้องการความเร็วมากกว่าความสดใหม่ tuyệt đối

ตัวอย่าง:

            
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        const fetchPromise = fetch(event.request).then(networkResponse => {
          caches.open('my-cache').then(cache => {
            cache.put(event.request, networkResponse.clone());
            return networkResponse;
          });
        });
        return response || fetchPromise;
      })
  );
});

            

6. แคชแล้วตามด้วยเครือข่าย (Cache, then Network)

คล้ายกับ stale-while-revalidate แต่ไม่มีการส่งคืนแอสเซทที่แคชไว้ทันที จะตรวจสอบแคชก่อน และหากมีแอสเซทอยู่เท่านั้น คำขอเครือข่ายจะดำเนินการในเบื้องหลังเพื่ออัปเดตแคช

การเลือกกลยุทธ์การแคชที่เหมาะสม

กลยุทธ์การแคชที่เหมาะสมที่สุดขึ้นอยู่กับความต้องการเฉพาะของแอปพลิเคชันของคุณ ควรพิจารณาปัจจัยต่างๆ เช่น:

ด้วยการเลือกกลยุทธ์การแคชที่เหมาะสมอย่างรอบคอบ คุณสามารถปรับปรุงประสิทธิภาพและประสบการณ์ผู้ใช้ของ PWA ของคุณได้อย่างมาก แม้ในสภาพแวดล้อมออฟไลน์ เครื่องมืออย่าง Workbox ([https://developers.google.com/web/tools/workbox](https://developers.google.com/web/tools/workbox)) สามารถช่วยให้การนำกลยุทธ์เหล่านี้ไปใช้ง่ายขึ้น

การซิงโครไนซ์เบื้องหลัง: การจัดการการเปลี่ยนแปลงข้อมูลขณะออฟไลน์

การซิงโครไนซ์เบื้องหลังช่วยให้ PWA ของคุณสามารถทำงานในเบื้องหลังได้ แม้ว่าผู้ใช้จะออฟไลน์อยู่ก็ตาม สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการจัดการการส่งฟอร์ม, การอัปเดตข้อมูล และการดำเนินงานอื่นๆ ที่ต้องใช้การเชื่อมต่อเครือข่าย `BackgroundSyncManager` API ช่วยให้คุณสามารถลงทะเบียนงานที่จะดำเนินการเมื่อมีเครือข่ายใช้งานได้

การลงทะเบียนงานซิงค์เบื้องหลัง

ในการลงทะเบียนงานซิงค์เบื้องหลัง คุณต้องใช้เมธอด `register` ของ `BackgroundSyncManager` เมธอดนี้รับชื่อแท็กที่ไม่ซ้ำกันเป็นอาร์กิวเมนต์ ชื่อแท็กจะระบุงานเฉพาะที่จะต้องดำเนินการ

ตัวอย่าง:

            
self.addEventListener('sync', event => {
  if (event.tag === 'my-sync-task') {
    event.waitUntil(doSomeWork());
  }
});

            

การจัดการอีเวนต์ซิงค์

เมื่อเบราว์เซอร์ตรวจพบการเชื่อมต่อเครือข่าย มันจะส่งอีเวนต์ `sync` ไปยัง service worker คุณสามารถดักฟังอีเวนต์นี้และดำเนินการที่จำเป็นได้ เช่น การส่งข้อมูลไปยังเซิร์ฟเวอร์

ตัวอย่าง:

            
async function doSomeWork() {
  // Retrieve data from IndexedDB
  const data = await getDataFromIndexedDB();

  // Send data to the server
  try {
    const response = await fetch('/api/sync', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json'
      }
    });

    if (response.ok) {
      // Clear the data from IndexedDB
      await clearDataFromIndexedDB();
    } else {
      // Handle errors
      console.error('Sync failed:', response.status);
      throw new Error('Sync failed');
    }
  } catch (error) {
    // Handle network errors
    console.error('Network error:', error);
    throw error;
  }
}

            

ตัวอย่าง: การส่งฟอร์มแบบออฟไลน์

ลองนึกภาพสถานการณ์ที่ผู้ใช้กรอกแบบฟอร์มขณะออฟไลน์ service worker สามารถจัดเก็บข้อมูลฟอร์มใน IndexedDB และลงทะเบียนงานซิงค์เบื้องหลัง เมื่อมีเครือข่ายใช้งานได้ service worker จะดึงข้อมูลฟอร์มจาก IndexedDB และส่งไปยังเซิร์ฟเวอร์

  1. ผู้ใช้กรอกแบบฟอร์มและคลิกส่งขณะออฟไลน์
  2. ข้อมูลฟอร์มจะถูกเก็บไว้ใน IndexedDB
  3. มีการลงทะเบียนงานซิงค์เบื้องหลังด้วยแท็กที่ไม่ซ้ำกัน (เช่น `form-submission`)
  4. เมื่อเครือข่ายพร้อมใช้งาน อีเวนต์ `sync` จะถูกทริกเกอร์
  5. service worker จะดึงข้อมูลฟอร์มจาก IndexedDB และส่งไปยังเซิร์ฟเวอร์
  6. หากการส่งสำเร็จ ข้อมูลฟอร์มจะถูกลบออกจาก IndexedDB

การแจ้งเตือนแบบพุช: ดึงดูดผู้ใช้ด้วยการอัปเดตที่ทันท่วงที

การแจ้งเตือนแบบพุชช่วยให้ PWA ของคุณสามารถส่งการอัปเดตและข้อความที่ทันท่วงทีไปยังผู้ใช้ได้ แม้ว่าแอปจะไม่ได้ทำงานอยู่ในเบราว์เซอร์ก็ตาม ซึ่งสามารถปรับปรุงการมีส่วนร่วมและการรักษาผู้ใช้ได้อย่างมาก Push API และ Notifications API ทำงานร่วมกันเพื่อส่งการแจ้งเตือนแบบพุช

การสมัครรับการแจ้งเตือนแบบพุช

ในการรับการแจ้งเตือนแบบพุช ผู้ใช้จะต้องให้สิทธิ์แก่ PWA ของคุณก่อน คุณสามารถใช้ `PushManager` API เพื่อให้ผู้ใช้สมัครรับการแจ้งเตือนแบบพุช

ตัวอย่าง:

            
navigator.serviceWorker.ready.then(registration => {
  registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: 'YOUR_PUBLIC_VAPID_KEY'
  })
  .then(subscription => {
    // Send subscription details to your server
    sendSubscriptionToServer(subscription);
  })
  .catch(error => {
    console.error('Failed to subscribe:', error);
  });
});

            

สำคัญ: แทนที่ `YOUR_PUBLIC_VAPID_KEY` ด้วย VAPID (Voluntary Application Server Identification) key จริงของคุณ VAPID key ใช้เพื่อระบุแอปพลิเคชันเซิร์ฟเวอร์ของคุณและรับรองว่าการแจ้งเตือนแบบพุชจะถูกส่งอย่างปลอดภัย

การจัดการการแจ้งเตือนแบบพุช

เมื่อได้รับการแจ้งเตือนแบบพุช service worker จะส่งอีเวนต์ `push` คุณสามารถดักฟังอีเวนต์นี้และแสดงการแจ้งเตือนแก่ผู้ใช้ได้

ตัวอย่าง:

            
self.addEventListener('push', event => {
  const payload = event.data ? event.data.text() : 'No payload';

  event.waitUntil(
    self.registration.showNotification('My PWA', {
      body: payload,
      icon: 'icon.png'
    })
  );
});

            

การปรับแต่งการแจ้งเตือนแบบพุช

Notifications API ช่วยให้คุณสามารถปรับแต่งลักษณะและพฤติกรรมของการแจ้งเตือนแบบพุชได้ คุณสามารถระบุชื่อเรื่อง, เนื้อหา, ไอคอน, ป้าย และตัวเลือกอื่นๆ ได้

ตัวอย่าง:

            
self.addEventListener('push', event => {
  const data = event.data.json();
  const title = data.title || 'My PWA';
  const options = {
    body: data.body || 'No message',
    icon: data.icon || 'icon.png',
    badge: data.badge || 'badge.png',
    vibrate: [200, 100, 200],
    data: { // Custom data that you can access when the user clicks the notification
      url: data.url || '/'
    },
    actions: [
      {action: 'explore', title: 'Explore this new world',
        icon: 'images/checkmark.png'},
      {action: 'close', title: 'Close',
        icon: 'images/xmark.png'},
    ]
  };

  event.waitUntil(self.registration.showNotification(title, options));
});


self.addEventListener('notificationclick', function(event) {
  event.notification.close();

  // Check if the user clicked on an action.
  if (event.action === 'explore') {
    clients.openWindow(event.notification.data.url);
  } else {
    // Default action: open the app.
    clients.openWindow('/');
  }
});

            

ตัวอย่าง: การแจ้งเตือนข่าวสาร

แอปพลิเคชันข่าวสามารถใช้การแจ้งเตือนแบบพุชเพื่อแจ้งเตือนผู้ใช้เกี่ยวกับข่าวด่วนได้ เมื่อมีการเผยแพร่บทความใหม่ เซิร์ฟเวอร์จะส่งการแจ้งเตือนแบบพุชไปยังอุปกรณ์ของผู้ใช้ โดยแสดงสรุปสั้นๆ ของบทความ จากนั้นผู้ใช้สามารถคลิกที่การแจ้งเตือนเพื่อเปิดบทความฉบับเต็มใน PWA

รูปแบบ Service Worker ขั้นสูง

1. การวิเคราะห์ข้อมูลแบบออฟไลน์

ติดตามพฤติกรรมของผู้ใช้แม้ในขณะที่พวกเขาออฟไลน์ โดยการจัดเก็บข้อมูลการวิเคราะห์ไว้ในเครื่อง และส่งไปยังเซิร์ฟเวอร์เมื่อมีเครือข่ายใช้งานได้ สามารถทำได้โดยใช้ IndexedDB และ Background Sync

2. การกำหนดเวอร์ชันและการอัปเดต

ใช้กลยุทธ์การกำหนดเวอร์ชันที่แข็งแกร่งสำหรับ service worker ของคุณเพื่อให้แน่ใจว่าผู้ใช้จะได้รับการอัปเดตล่าสุดเสมอโดยไม่รบกวนประสบการณ์ของพวกเขา ใช้เทคนิค cache busting เพื่อทำให้แอสเซทที่แคชไว้เก่าใช้งานไม่ได้

3. Service Worker แบบโมดูล

จัดระเบียบโค้ด service worker ของคุณเป็นโมดูลเพื่อปรับปรุงความสามารถในการบำรุงรักษาและการอ่าน ใช้ JavaScript modules (ESM) หรือ module bundler เช่น Webpack หรือ Rollup

4. การแคชแบบไดนามิก

แคชแอสเซทแบบไดนามิกตามการโต้ตอบของผู้ใช้และรูปแบบการใช้งาน ซึ่งจะช่วยเพิ่มประสิทธิภาพขนาดของแคชและปรับปรุงประสิทธิภาพ

แนวทางปฏิบัติที่ดีที่สุดสำหรับการพัฒนา Service Worker

สรุป

JavaScript service worker เป็นเครื่องมือที่ทรงพลังสำหรับการสร้าง PWA ที่แข็งแกร่ง, มีประสิทธิภาพ และน่าสนใจ ด้วยการทำความเข้าใจวงจรชีวิตของ service worker และการใช้กลยุทธ์การแคชที่เหมาะสม, การซิงโครไนซ์เบื้องหลัง และการแจ้งเตือนแบบพุช คุณสามารถสร้างประสบการณ์ผู้ใช้ที่ยอดเยี่ยมได้ แม้ในสภาพแวดล้อมออฟไลน์ บทความนี้ได้สำรวจรูปแบบ service worker ที่สำคัญและแนวทางปฏิบัติที่ดีที่สุดเพื่อเป็นแนวทางในการสร้าง PWA ที่ประสบความสำเร็จสำหรับผู้ใช้ทั่วโลก ในขณะที่เว็บยังคงพัฒนาต่อไป service worker จะมีบทบาทสำคัญมากขึ้นในการกำหนดอนาคตของการพัฒนาเว็บ

อย่าลืมปรับรูปแบบเหล่านี้ให้เข้ากับความต้องการของแอปพลิเคชันของคุณโดยเฉพาะ และให้ความสำคัญกับประสบการณ์ของผู้ใช้เสมอ ด้วยการใช้ประโยชน์จากพลังของ service worker คุณสามารถสร้าง PWA ที่ไม่เพียงแต่ใช้งานได้ดี แต่ยังน่าใช้ ไม่ว่าผู้ใช้จะอยู่ที่ใดหรือมีการเชื่อมต่อเครือข่ายแบบใด

แหล่งข้อมูลเพิ่มเติม: